package br.mikhas.nova;

import java.io.File;
import java.io.FilenameFilter;
import java.util.Scanner;

public final class Compiler {

	private Compiler() {
	}

	public static void compile(File root) throws Exception {
		if (root.isFile())
			root = root.getParentFile();

		new Compiler().doCompile(root);
	}

	private void doCompile(File root) throws Exception {
		File[] sources = root.listFiles(new FilenameFilter() {
			@Override
			public boolean accept(File dir, String name) {
				return name.endsWith(".nos");
			}
		});

		CompilationUnit cu = new CompilationUnit();

		for (File source : sources) {
			compileSource(cu, source);
		}
	}

	private void compileSource(CompilationUnit cu, File source)
			throws Exception {
		Scanner scanner = new Scanner(source);
		while (scanner.hasNext()) {
			String line = scanner.next();
			if (line.startsWith("+class")) {
				this.compileClass(scanner, line, cu);
			}
		}
	}

	private void compileClass(Scanner scanner, String def, CompilationUnit cu) {
		String name = def.substring("+class ".length()).trim();
		ClassEntry cls = cu.getClass(name);

		while (scanner.hasNext()) {
			String line = scanner.next();

			if (line.startsWith("+field")) {
				FieldEntry field = this.compileField(scanner, line, cu);
				field.declaringClass = cls;
			}
		}
	}

	private FieldEntry compileField(Scanner scanner, String line,
			CompilationUnit cu) {
		line = line.substring("+field".length());
		String[] def = StringUtils.split(line, ' ');

		TypeEntry type = cu.getType(def[0]);
		StringEntry name = cu.getString(def[1]);

		FieldEntry f = new FieldEntry();
		f.name = name;
		f.type = type;
		return f;
	}
}
